﻿using System;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Collections.Generic;
using System.Web.SessionState;
using System.Web;
using Zor_Tools;

namespace Zor_Web.Tools
{
    /// <summary>
    /// UplaodServer 的摘要说明
    /// </summary>
    public class UploadServer : IHttpHandler, IRequiresSessionState
    {
        private readonly string filepath = "/upload";
        public void ProcessRequest(HttpContext context)
        {
            //取得处事类型
            string action = DTRequest.GetQueryString("action");

            switch (action)
            {
                case "UpLoadImg": //图片
                    UpLoadImg(context);
                    break;
                case "UpLoadFile": //附件文件
                    UpLoadFile(context);
                    break;
                default: //普通上传
                    UpLoadFile(context);
                    break;
            }
        }

        #region - 上传文件分布处理 -
        private void UpLoadFile(HttpContext context)
        {
            UpLoadFile(context, filepath + "/File", true);
        }
        private void UpLoadImg(HttpContext context)
        {
            UpLoadFile(context, filepath + "/Img", true);
        }
        #endregion

        private void UpLoadFile(HttpContext context, string filepath, bool Istemp)
        {
            string _delfile = DTRequest.GetString("DelFilePath");
            HttpPostedFile _upfile = context.Request.Files["Filedata"];
            bool _iswater = false; //默认不打水印
            bool _isthumbnail = false; //默认不生成缩略图

            if (DTRequest.GetQueryString("IsWater") == "1")
                _iswater = true;
            if (DTRequest.GetQueryString("IsThumbnail") == "1")
                _isthumbnail = true;
            if (_upfile == null)
            {
                context.Response.Write("{\"status\": 0, \"msg\": \"请选择要上传文件！\"}");
                return;
            }
            UpLoad upFiles = new UpLoad();
            string msg = upFiles.fileSaveAs(_upfile, _isthumbnail, _iswater, upFiles.GetUpLoadPath(filepath, 0, Istemp));
            //删除已存在的旧文件，旧文件不为空且应是上传文件，防止跨目录删除
            if (!string.IsNullOrEmpty(_delfile) && _delfile.IndexOf("../") == -1
                && _delfile.ToLower().StartsWith(filepath.ToLower()))
            {
                upFiles.DeleteUpFile(_delfile);
            }
            //返回成功信息
            context.Response.Write(msg);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    public partial class UpLoad
    {
        private readonly int imgmaxheight = 0;
        private readonly int imgmaxwidth = 1024;
        private readonly int thumbnailheight = 300;
        private readonly int thumbnailwidth = 300;
        private readonly int watermarktype = 2;
        private readonly string fileextension = "jpg,jpge,png,gif,doc,docx,xls,rar,xlsx,pdf";
        private readonly string videoextension = "flv,mp3,mp4,avi";
        private readonly int videosize = 102400;
        private readonly int imgsize = 10240;
        private readonly int attachsize = 51200;

        public UpLoad()
        {
        }

        /// <summary>
        /// 文件上传方法
        /// </summary>
        /// <param name="postedFile">文件流</param>
        /// <param name="isThumbnail">是否生成缩略图</param>
        /// <param name="isWater">是否打水印</param>
        /// <param name="_upLoadPath">上传目录相对路径</param>
        /// <returns>上传后文件信息</returns>
        public string fileSaveAs(HttpPostedFile postedFile, bool isThumbnail, bool isWater, string _upLoadPath)
        {
            try
            {
                string fileExt = SqlFilterHelper.GetFileExt(postedFile.FileName); //文件扩展名，不含“.”
                int fileSize = postedFile.ContentLength; //获得文件大小，以字节为单位
                string fileName = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf(@"\") + 1); //取得原文件名
                string newFileName = this.GetRamCodeNYRNone() + "." + fileExt; //随机生成新的文件名
                string newThumbnailFileName = "thumb_" + newFileName; //随机生成缩略图文件名
                string upLoadPath = _upLoadPath; //上传目录相对路径
                string fullUpLoadPath = SqlFilterHelper.GetMapPath(upLoadPath); //上传目录的物理路径
                string newFilePath = upLoadPath + newFileName; //上传后的路径
                string newThumbnailPath = upLoadPath + newThumbnailFileName; //上传后的缩略图路径

                //检查文件扩展名是否合法
                if (!CheckFileExt(fileExt))
                {
                    return "{\"status\": 0, \"msg\": \"不允许上传" + fileExt + "类型的文件！\"}";
                }
                //检查文件大小是否合法
                if (!CheckFileSize(fileExt, fileSize))
                {
                    return "{\"status\": 0, \"msg\": \"文件超过限制的大小！\"}";
                }
                //检查上传的物理路径是否存在，不存在则创建
                if (!Directory.Exists(fullUpLoadPath))
                {
                    Directory.CreateDirectory(fullUpLoadPath);
                }

                //保存文件
                postedFile.SaveAs(fullUpLoadPath + newFileName);
                //如果是图片，检查图片是否超出最大尺寸，是则裁剪
                if (IsImage(fileExt) && (this.imgmaxheight > 0 || this.imgmaxwidth > 0))
                {
                    Thumbnail.MakeThumbnailImage(fullUpLoadPath + newFileName, fullUpLoadPath + newFileName,
                        this.imgmaxwidth, this.imgmaxheight);
                }
                //如果是图片，检查是否需要生成缩略图，是则生成
                if (IsImage(fileExt) && isThumbnail && this.thumbnailwidth > 0 && this.thumbnailheight > 0)
                {
                    Thumbnail.MakeThumbnailImage(fullUpLoadPath + newFileName, fullUpLoadPath + newThumbnailFileName,
                        this.thumbnailwidth, this.thumbnailheight, "Cut");
                }
                else
                {
                    newThumbnailPath = newFilePath; //不生成缩略图则返回原图
                }

                //处理完毕，返回JOSN格式的文件信息
                return "{\"status\": 1, \"msg\": \"上传文件成功！\", \"name\": \""
                    + fileName + "\", \"path\": \"" + newFilePath + "\", \"thumb\": \""
                    + newThumbnailPath + "\", \"size\": " + fileSize + ", \"ext\": \"" + fileExt + "\"}";
            }
            catch
            {
                return "{\"status\": 0, \"msg\": \"上传过程中发生意外错误！\"}";
            }
        }


        /// <summary>
        /// 删除上传的文件(及缩略图)
        /// </summary>
        /// <param name="_filepath"></param>
        public void DeleteUpFile(string _filepath)
        {
            if (string.IsNullOrEmpty(_filepath))
            {
                return;
            }
            string fullpath = SqlFilterHelper.GetMapPath(_filepath); //原图
            if (File.Exists(fullpath))
            {
                File.Delete(fullpath);
            }
            if (_filepath.LastIndexOf("/") >= 0)
            {
                string thumbnailpath = _filepath.Substring(0, _filepath.LastIndexOf("/")) + "/thumb_" + _filepath.Substring(_filepath.LastIndexOf("/") + 1);
                string fullTPATH = SqlFilterHelper.GetMapPath(thumbnailpath); //宿略图
                if (File.Exists(fullTPATH))
                {
                    File.Delete(fullTPATH);
                }
            }
        }

        #region 私有方法

        /// <summary>
        /// 返回上传目录相对路径(自定义路径)
        /// </summary>
        public string GetUpLoadPath(string filepath, int filesave, bool Istemp)
        {
            string path = filepath + "/"; //站点目录+上传目录
            if (Istemp)
            {
                switch (filesave)
                {
                    case 0: //按年/月日存入不同的文件夹
                        path += DateTime.Now.ToString("yyyy") + "/" + DateTime.Now.ToString("MMdd") + "/";
                        break;
                    case 1: //按年月日每天一个文件夹
                        path += DateTime.Now.ToString("yyyyMMdd") + "/";
                        break;
                    default: //按年月/日存入不同的文件夹
                        path += DateTime.Now.ToString("yyyyMM") + "/" + DateTime.Now.ToString("dd") + "/";
                        break;
                }
            }
            return path;
        }

        /// <summary>
        /// 是否需要打水印
        /// </summary>
        /// <param name="_fileExt">文件扩展名，不含“.”</param>
        private bool IsWaterMark(string _fileExt)
        {
            //判断是否开启水印
            if (this.watermarktype > 0)
            {
                //判断是否可以打水印的图片类型
                ArrayList al = new ArrayList();
                al.Add("bmp");
                al.Add("jpeg");
                al.Add("jpg");
                al.Add("png");
                if (al.Contains(_fileExt.ToLower()))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 是否为图片文件
        /// </summary>
        /// <param name="_fileExt">文件扩展名，不含“.”</param>
        private bool IsImage(string _fileExt)
        {
            ArrayList al = new ArrayList();
            al.Add("bmp");
            al.Add("jpeg");
            al.Add("jpg");
            al.Add("gif");
            al.Add("png");
            if (al.Contains(_fileExt.ToLower()))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 检查是否为合法的上传文件
        /// </summary>
        private bool CheckFileExt(string _fileExt)
        {
            //检查危险文件
            string[] excExt = { "asp", "aspx", "ashx", "asa", "asmx", "asax", "php", "jsp", "htm", "html" };
            for (int i = 0; i < excExt.Length; i++)
            {
                if (excExt[i].ToLower() == _fileExt.ToLower())
                {
                    return false;
                }
            }
            //检查合法文件
            string[] allowExt = (this.fileextension + "," + this.videoextension).Split(',');
            for (int i = 0; i < allowExt.Length; i++)
            {
                if (allowExt[i].ToLower() == _fileExt.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 检查文件大小是否合法
        /// </summary>
        /// <param name="_fileExt">文件扩展名，不含“.”</param>
        /// <param name="_fileSize">文件大小(B)</param>
        private bool CheckFileSize(string _fileExt, int _fileSize)
        {
            //将视频扩展名转换成ArrayList
            ArrayList lsVideoExt = new ArrayList(this.videoextension.ToLower().Split(','));
            //判断是否为图片文件
            if (IsImage(_fileExt))
            {
                if (this.imgsize > 0 && _fileSize > this.imgsize * 1024)
                {
                    return false;
                }
            }
            else if (lsVideoExt.Contains(_fileExt.ToLower()))
            {
                if (this.videosize > 0 && _fileSize > this.videosize * 1024)
                {
                    return false;
                }
            }
            else
            {
                if (this.attachsize > 0 && _fileSize > this.attachsize * 1024)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 生成无日期时分秒+16位字母数字混合随机码
        /// </summary>
        /// <returns></returns>
        private string GetRamCodeNYRNone()
        {
            return DateTime.Now.ToString("HHmmssffff") + "_" + SqlFilterHelper.GetCheckCode(16);
        }

        #endregion

    }
}